using System;
using System.Collections;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using GrapeCity.Forguncy.Commands;
using Newtonsoft.Json.Linq;

namespace PdfOperationCommand
{
    [Category("PDF文件操作")]
    public abstract class BaseServerCommand : Command
    {
        public override CommandScope GetCommandScope()
        {
            return CommandScope.ServerSide;
        }

        protected async Task<ArrayList> GetArrayListParam(IServerCommandExecuteContext dataContext, object formula)
        {
            if (formula == null)
            {
                throw new ArgumentException("The argument/formula was not set.");
            }

            var rawData = await GetParamValue(dataContext, formula);

            var data = new ArrayList();
            switch (rawData)
            {
                case null:
                    throw new ArgumentException("[" + formula + "] is null.");
                case IEnumerable enumerableData:
                {
                    foreach (var item in enumerableData)
                    {
                        data.Add(item);
                    }

                    break;
                }
                default:
                {
                    if (rawData.GetType() == typeof(Array))
                    {
                        data.AddRange((Array)rawData);
                    }
                    else if (rawData.GetType() == typeof(JArray))
                    {
                        data.AddRange(((JArray)rawData).ToArray());
                    }
                    else
                    {
                        throw new ArgumentException("[" + formula + "]'s type was " + rawData.GetType() +
                                                    ", should be an ArrayList， Array or JArray.");
                    }

                    break;
                }
            }

            return data;
        }

        protected async Task<object> GetParamValue(IServerCommandExecuteContext dataContext, object formula,
            bool shouldCheckNull = true)
        {
            if (formula != null) return await dataContext.EvaluateFormulaAsync(formula);
            if (shouldCheckNull)
            {
                throw new ArgumentException("The parameter/formula was not set.");
            }

            return null;
        }
    }
}